using System.Windows.Media;

namespace DimensionsHelper.Client.Controls;

public record HsvColor(double H, double S, double V)
{
    
    public static HsvColor FromRgb(double r, double g, double b)
    {
        // 转换HSV颜色的方法步骤：
        // 1. 将RGB转换为0-1之间的百分比数据，即 r = R / 255
        // 2. 计算r, g, b中的最小值 min 和 最大值 max
        // 3. 计算最大值和最小值之间的插值 delta
        // 4. 饱和度 S = max == 0 ? 0 : delta / max 
        // 5. 明度 V = max
        // 6. 色相:
        //    1> delta == 0 -> H = 0
        //    2> max   == r -> H = ((g - b) / delta) + (g < b ? 6 : 0)
        //    3> max   == g -> H = ((b - r) / delta) + 2
        //    4> max   == b -> H = ((r - g) / delta) + 4
        //    5> 转换为角度: H = H * 60

        r /= 255d;
        g /= 255d;
        b /= 255d;

        double max = Math.Max(r, Math.Max(g, b));
        double min = Math.Min(r, Math.Min(g, b));
        double d = max - min;

        // H
        double h;
        if (max == min)
        {
            h = 0;
        }
        else
        {
            if (max == r)
            {
                h = ((g - b) / d) + (g < b ? 6 : 0);
            }
            else if (max == g)
            {
                h = ((b - r) / d) + 2;
            }
            else
            {
                h = ((r - g) / d) + 4;
            }

            h /= 6;
        }

        // S
        double s = max == 0 ? 0 : d / max;

        return new HsvColor(Math.Round(h, 4), Math.Round(s, 4), Math.Round(max, 4));
    }


    public Color ToRgb()
    {
        return ToArgb(25);
    }


    public Color ToArgb(byte alpha)
    {
        double i = Math.Floor(H * 6);
        double f = (H * 6) - i;
        double p = V * (1 - S);
        double q = V * (1 - (f * S));
        double t = V * (1 - ((1 - f) * S));

        double r = 0, g = 0, b = 0;

        switch (i % 6)
        {
            case 0:
                r = V;
                g = t;
                b = p;
                break;

            case 1:
                r = q;
                g = V;
                b = p;
                break;

            case 2:
                r = p;
                g = V;
                b = t;
                break;

            case 3:
                r = p;
                g = q;
                b = V;
                break;

            case 4:
                r = t;
                g = p;
                b = V;
                break;

            case 5:
                r = V;
                g = p;
                b = q;
                break;
        }

        return Color.FromArgb(alpha, (byte)(r * 255), (byte)(g * 255), (byte)(b * 255));

    }
    
}